from django.db import models
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _

import cPickle
import base64

class Project(models.Model):
    obj_types=(
        ('max', _('maximize')),
        ('min', _('minimize')),
    )
    pro_desc={
        'proname': _('Project name'),
        'objname': _('Objective name'),
        'objtype': _('Objective type'),
        'n': _('Decision variables count'),
        'm': _('Constraints count'),
        'nonzero': _('Positive only variables'),
        'binary': _('Binary only variables'),
        'integer': _('Integer only variables'),
        'created': _('Created'),
        'changed': _('Last changed'),
        'viewtype': _('View type'),
    }
    view_types = ((0, "classic"), (1, "flat"))

    user = models.ForeignKey(User)
    proname = models.CharField(pro_desc['proname'], max_length=26)
    objname = models.CharField(pro_desc['objname'], max_length=26)
    objtype = models.CharField(pro_desc['objtype'], max_length=3, choices=obj_types)
    n = models.PositiveIntegerField(pro_desc['n'], max_length=3)
    m = models.PositiveIntegerField(pro_desc['m'], max_length=3)
    nonzero = models.BooleanField(pro_desc['nonzero'], default=True)
    binary = models.BooleanField(pro_desc['binary'], default=False)
    integer = models.BooleanField(pro_desc['integer'], default=False)
    created = models.DateTimeField(pro_desc['created'], auto_now_add=True)
    changed = models.DateTimeField(pro_desc['changed'], auto_now=True)
    viewtype = models.PositiveIntegerField(pro_desc['viewtype'], choices=view_types, null=True)

    def __unicode__(self):
        return '%s' % (self.id)

    class Admin:
        pass

class Project_Data(models.Model):
    project = models.OneToOneField(Project, primary_key=True)
    # don't access 'encoded_data' directly, use the 'data' property instead, etc
    encoded_data = models.TextField('Encoded Data', blank=True, null=False)
    encoded_options = models.TextField('Encoded Options', blank=True, null=False)
    encoded_solution = models.TextField('Encoded Solution', blank=True, null=False)
    encoded_solfile = models.TextField('Encoded Solution File', blank=True, null=False)
    encoded_bodfile = models.TextField('Encoded Bounds File', blank=True, null=False)

    def _decode(self, xdata):
        pickled = base64.decodestring(xdata)
        try:
            return cPickle.loads(pickled)
        except:
            return {}
    
    def _encode(self, xdata):
        pickled = cPickle.dumps(xdata)
        encoded_data = base64.encodestring(pickled)
        return encoded_data

    def _get_data(self):
        return self._decode(self.encoded_data)
    def _set_data(self, data):
        self.encoded_data = self._encode(data)
    data = property(_get_data, _set_data)

    def _get_solution(self):
        return self._decode(self.encoded_solution)
    def _set_solution(self, solution):
        self.encoded_solution = self._encode(solution)
    solution = property(_get_solution, _set_solution)

    def _get_options(self):
        return self._decode(self.encoded_options)
    def _set_options(self, options):
        self.encoded_options = self._encode(options)
    options = property(_get_options, _set_options)

    def _get_solfile(self):
        return self._decode(self.encoded_solfile)
    def _set_solfile(self, solfile):
        self.encoded_solfile = self._encode(solfile)
    solfile = property(_get_solfile, _set_solfile)

    def _get_bodfile(self):
        return self._decode(self.encoded_bodfile)
    def _set_bodfile(self, bodfile):
        self.encoded_bodfile = self._encode(bodfile)
    bodfile = property(_get_bodfile, _set_bodfile)

    def __unicode__(self):
        return '%s'  % (self.project_id)

    class Admin:
        pass
